/**
 * 文件：RemoteDataService.java
 * 包名：com.ronri.db;   --- 正式发布时需要修正
 * 说明：远程数据服务
 * 作者：MS During
 * 日期：2017/5/5
 * 历史：
 */
package com.ronri.db;


import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.ronri.ams.SystemEnvironmental;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class RemoteDataService {

    private static final int TIME_OUT = 10 * 1000;   //超时时间
    private static final String CHARSET = "utf-8"; //设置编码

    // 接口事件定义
    public interface OnRemoteDataEvent {
        // 返回获取的结果
        void OnResultEvent(String szString);

        // 执行状态
        void OnRuningState(int nStatus);

        // 获取参数
        String OnGetCustomParam();
    }

    // 接口事件
    private OnRemoteDataEvent mEvent = null;

    /***
     * 通过消息机制操作网络数据
     */
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData();

            int nCommand = bundle.getInt("MessageCommand");
            switch (nCommand) {
                // 开始获取数据
                case SystemEnvironmental.StartGetDataFromServer:
                    // 显示进度条
                    if (mEvent != null) {
                        // 回调开始状态
                        mEvent.OnRuningState(SystemEnvironmental.StartGetDataFromServer);
                    }
                    break;
                // 结束获取数据
                case SystemEnvironmental.StopGetDataFromServer:
                    // 关闭进度条，并返回结果
                    if (mEvent != null) {
                        String szResult = bundle.getString("Result");

                        // 回调停止状态
                        mEvent.OnRuningState(SystemEnvironmental.StopGetDataFromServer);

                        // 回调结果
                        mEvent.OnResultEvent(szResult);
                    }
                    break;
                // 网络错误
                case SystemEnvironmental.GetDataFromServerError:
                    // 关闭进度条，并返回结果
                    if (mEvent != null) {
                        String szResult = bundle.getString("Result");

                        // 回调停止状态
                        mEvent.OnRuningState(SystemEnvironmental.GetDataFromServerError);

                        // 回调结果
                        mEvent.OnResultEvent("网络连接失败！");
                    }
                    break;
                // 数据获取中...
                case SystemEnvironmental.RuningGetDataFromServerStatus:
                    if (mEvent != null) {
                        mEvent.OnRuningState(SystemEnvironmental.StartGetDataFromServer);
                    }
                    break;
            }

            super.handleMessage(msg);
        }
    };

    /**
     * 以Get/Post的方式发送数据
     *
     * @param szRemoteUrl
     * @param szParam
     * @param szMode
     */
    private void sendHttpConnectionDataWithGet(String szRemoteUrl, String szParam, String szMode) {
        try {
            String szResult = "";

            // 判断传送配置是否为POST/GET，如果不是则默认为POST
            if (szMode.toLowerCase() != "post") {
                if (szMode.toLowerCase() != "get") {
                    szMode = "POST";
                }
            }

            // 转换URL格式
            URL url = new URL(szRemoteUrl);

            {
                // 获取消息
                Message msg = handler.obtainMessage();

                Bundle bundle = new Bundle();
                bundle.putInt("MessageCommand", SystemEnvironmental.StartGetDataFromServer);

                // 设置消息数据
                msg.setData(bundle);

                // 发送消息
                handler.sendMessage(msg);
            }

            // 链接远程地址
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.setRequestMethod(szMode);
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setInstanceFollowRedirects(true);
            urlConnection.setRequestProperty("Content-Type", "application/json");

            // 组合参数
            DataOutputStream outputStream = new DataOutputStream(urlConnection.getOutputStream());

            // 写入参数
            outputStream.writeBytes(szParam);
            // 写入流
            outputStream.flush();
            // 关闭
            outputStream.close();

            // 判断请求是否成功
            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStreamReader inputStreamReader = new InputStreamReader(urlConnection.getInputStream());
                BufferedReader buffer = new BufferedReader(inputStreamReader);
                String inputLine = null;
                while ((inputLine = buffer.readLine()) != null) {
                    szResult += inputLine;
                }

                // 关闭流
                inputStreamReader.close();

                {
                    // 获取消息
                    Message msg = handler.obtainMessage();

                    Bundle bundle = new Bundle();
                    bundle.putInt("MessageCommand", SystemEnvironmental.StopGetDataFromServer);
                    bundle.putString("Result", szResult);

                    // 设置消息数据
                    msg.setData(bundle);

                    // 发送消息
                    handler.sendMessage(msg);
                }
            }
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /***
     * 远程数据获取线程
     */
    private class HttpConnectionRunable implements Runnable {

        public final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

        // 远程地址
        String mRemoteUrl = null;

        // 参数
        String mParam = null;

        // 模式
        String mMode = "POST";

        /**
         * 统一为请求添加头信息
         *
         * @return
         */
        private Request.Builder addHeaders() {
            Request.Builder builder = new Request.Builder()
                    .addHeader("Connection", "keep-alive")
                    .addHeader("platform", "2")
                    .addHeader("phoneModel", Build.MODEL)
                    .addHeader("systemVersion", Build.VERSION.RELEASE)
                    .addHeader("appVersion", "3.2.0");
            return builder;
        }

        /***
         * 构造函数
         *
         * @param szRemoteUrl
         * @param szParam
         * @param szMode
         */
        public HttpConnectionRunable(String szRemoteUrl, final String szParam, final String szMode) {
            super();

            mRemoteUrl = szRemoteUrl;
            mParam = szParam;
            mMode = szMode;
        }

        @Override
        public int hashCode() {
            return super.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            return super.equals(obj);
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }

        @Override
        public String toString() {
            return super.toString();
        }

        @Override
        protected void finalize() throws Throwable {
            super.finalize();
        }

        @Override
        public void run() {
            try {
                String szResult = "";

                // 判断传送配置是否为POST/GET，如果不是则默认为POST
                if (mMode.toLowerCase().equals("post")) {
                    if (mMode.toLowerCase().equals("get")) {
                        mMode = "POST";
                    }
                }

                // 转换URL格式
                URL url = new URL(mRemoteUrl);

                {
                    // 获取消息
                    Message msg = handler.obtainMessage();

                    Bundle bundle = new Bundle();
                    bundle.putInt("MessageCommand", SystemEnvironmental.StartGetDataFromServer);

                    // 设置消息数据
                    msg.setData(bundle);

                    // 发送消息
                    handler.sendMessage(msg);
                }

                // HTTP发送控制
                OkHttpClient client = new OkHttpClient();

                try {
                    Response response = null;

                    if (mMode.equals("POST")) {
                        FormBody param = new FormBody.Builder().
                                add("addFrom", "1").
                                add("addMark", "android").
                                add("json", mParam).build();

                        RequestBody body = RequestBody.create(MediaType.parse("text/plain; charset=utf-8"), mParam);
                        Request request = new Request.Builder()
                                .url(url)
                                .post(param)
                                .build();

                        response = client.newCall(request).execute();
                    } else {
                        String szpurl = String.format("%s?%s", url, mParam);

                        Request request = new Request.Builder()
                                .url(szpurl)
                                .build();

                        response = client.newCall(request).execute();
                    }

                    if (response.isSuccessful()) {
                        szResult = response.body().string();
                        // 获取消息
                        Message msg = handler.obtainMessage();

                        Bundle bundle = new Bundle();
                        bundle.putInt("MessageCommand", SystemEnvironmental.StopGetDataFromServer);
                        bundle.putString("Result", szResult);

                        // 设置消息数据
                        msg.setData(bundle);

                        // 发送消息
                        handler.sendMessage(msg);
                    } else {
                        // 获取消息
                        Message msg = handler.obtainMessage();

                        Bundle bundle = new Bundle();
                        bundle.putInt("MessageCommand", SystemEnvironmental.GetDataFromServerError);
                        bundle.putString("Result", szResult);

                        // 设置消息数据
                        msg.setData(bundle);

                        // 发送消息
                        handler.sendMessage(msg);
                    }
                } catch (IOException ex) {
                    // 获取消息
                    Message msg = handler.obtainMessage();

                    Bundle bundle = new Bundle();
                    bundle.putInt("MessageCommand", SystemEnvironmental.GetDataFromServerError);
                    bundle.putString("Result", "");

                    // 设置消息数据
                    msg.setData(bundle);

                    // 发送消息
                    handler.sendMessage(msg);

                }
            } catch (MalformedURLException ex) {
                // 获取消息
                Message msg = handler.obtainMessage();

                Bundle bundle = new Bundle();
                bundle.putInt("MessageCommand", SystemEnvironmental.GetDataFromServerError);
                bundle.putString("Result", "");

                // 设置消息数据
                msg.setData(bundle);

                // 发送消息
                handler.sendMessage(msg);

            }
        }
    }


    /***
     * 上传文件
     */
    public class HttpPostFileToRemote implements Runnable {

        // 远程地址
        String mRemoteUrl = null;

        String mFilePath = null;

        Map<String, Object> mParam = null;
        List<String> mlistFile = new ArrayList<>();

        /***
         * 构造函数
         *
         * @param szUrl
         */
        public HttpPostFileToRemote(String szUrl, String szFilePath, Map<String, Object> Param) {
            mRemoteUrl = szUrl;
            mlistFile.add(szFilePath);
        }

        /***
         * 构造函数
         *
         * @param szUrl
         */
        public HttpPostFileToRemote(String szUrl, List<String> szFilePath, Map<String, Object> Param) {
            mParam = Param;
            mRemoteUrl = szUrl;
            mlistFile.addAll(szFilePath);
        }

        @Override
        public void run() {
            OkHttpClient client = new OkHttpClient();

            /* form的分割线,自己定义 */
            String boundary = "xx--------------------------------------------------------------xx";

            MultipartBody.Builder builder = new MultipartBody.Builder(boundary).setType(MultipartBody.FORM);

            builder.addFormDataPart("addFrom", "1");
            builder.addFormDataPart("addMark", "android");

            if (mParam != null){
                for(String key : mParam.keySet()){

                    if (key.toLowerCase().equals("addfrom"))
                        continue;

                    if (key.toLowerCase().equals("addmark"))
                        continue;

                    builder.addFormDataPart(key, mParam.get(key).toString());
                }
            }

            for(String iTem : mlistFile) {
                try {
                    File file = new File(iTem);
                    RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
                    String fileName = file.getName();

                    builder.addFormDataPart("files", fileName, fileBody);
                }catch (Exception ex){

                }
            }

            MultipartBody body = builder.build();

            /* 下边的就和post一样了 */
            Request request = new Request.Builder()
                    .url(mRemoteUrl)
                    .post(body)
                    .build();

            client.newCall(request).enqueue(new Callback() {

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    final String bodyStr = response.body().string();

                    if (response.isSuccessful() == true){
                        // 获取消息
                        Message msg = handler.obtainMessage();

                        Bundle bundle = new Bundle();
                        bundle.putInt("MessageCommand", SystemEnvironmental.StopGetDataFromServer);
                        bundle.putString("Result", bodyStr);

                        // 设置消息数据
                        msg.setData(bundle);

                        // 发送消息
                        handler.sendMessage(msg);
                    }else{
                        // 获取消息
                        Message msg = handler.obtainMessage();

                        Bundle bundle = new Bundle();
                        bundle.putInt("MessageCommand", SystemEnvironmental.GetDataFromServerError);

                        // 设置消息数据
                        msg.setData(bundle);

                        // 发送消息
                        handler.sendMessage(msg);
                    }
                }

                @Override
                public void onFailure(Call call, final IOException e) {
                    // 获取消息
                    Message msg = handler.obtainMessage();

                    Bundle bundle = new Bundle();
                    bundle.putInt("MessageCommand", SystemEnvironmental.GetDataFromServerError);

                    // 设置消息数据
                    msg.setData(bundle);

                    // 发送消息
                    handler.sendMessage(msg);
                }
            });
        }
    }

    /**
     * android上传文件到服务器
     *
     * @param file       需要上传的文件
     * @param RequestURL 请求的rul
     * @return 返回响应的内容
     */
    private String uploadFile(File file, String RequestURL, Map<String, String> param) {
        String result = null;
        String BOUNDARY = UUID.randomUUID().toString();  //边界标识   随机生成
        String PREFIX = "--", LINE_END = "\r\n";
        String CONTENT_TYPE = "multipart/form-data";   //内容类型


        return result;
    }

    /***
     * 获取数据
     *
     * @param szRemoteUrl
     * @param szParam
     * @param szMode
     */
    public void getRemoteData(String szRemoteUrl,
                              String szParam,
                              String szMode,
                              OnRemoteDataEvent event) {
        mEvent = event;

        // 创建一个新线程，用于从网络上获取文件
        new Thread(new HttpConnectionRunable(szRemoteUrl, szParam, szMode)).start(); // 开启线程
    }

    /***
     * 上传文件
     * @param szUrl
     * @param szFilePath
     * @param Param
     * @param event
     */
    public void postMFileToRemote(String szUrl,
                                  List<String> szFilePath,
                                  Map<String, Object> Param,
                                  OnRemoteDataEvent event) {

        mEvent = event;

        // 创建一个新线程，用于从网络上获取文件
        new Thread(new HttpPostFileToRemote(szUrl, szFilePath, Param)).start(); // 开启线程
    }


    /***
     * 上传文件
     * @param szUrl
     * @param szFilePath
     * @param Param
     * @param event
     */
    public void postFileToRemote(String szUrl, String szFilePath, Map<String, Object> Param,
                                 OnRemoteDataEvent event) {

        mEvent = event;

        // 创建一个新线程，用于从网络上获取文件
        new Thread(new HttpPostFileToRemote(szUrl, szFilePath, Param)).start(); // 开启线程
    }

    public void sendHttpClientDataWithPost() {

    }
}
